#include <tinx/debug.h>
#include <tinx/fs.h>
#include <tinx/task.h>
#include <tinx/string.h>
#include <tinx/assert.h>

#define NR_INODE 128

// inode 表
static inode_t inode_table[NR_INODE];

inode_t *get_free_inode()
{
    for (size_t i = 0; i < NR_INODE; i++)
    {
        inode_t *inode = &inode_table[i];
        if (!inode->super)
            return inode;
    }
    panic("No more inodes!\n");
}

inode_t *find_inode(super_t *super, idx_t nr)
{
    inode_t *inode = NULL;
    list_t *list = &super->inode_list;
    for (list_node_t *ptr = list->head.next; ptr != &list->tail; ptr = ptr->next)
    {
        inode_t *iptr = element_entry(inode_t, node, ptr);
        if (iptr->nr == nr)
        {
            inode = iptr;
            break;
        }
    }
    return inode;
}

inode_t *fit_inode(inode_t *inode)
{
    if (!inode->mount)
    {
        return inode;
    }
    super_t *super = inode->mount;
    assert(super->count && super->iroot);
    assert(inode == super->iroot || inode == super->imount);
    inode_t *iroot = super->iroot;
    iroot->count++;
    iput(inode);
    return iroot;
}

inode_t *get_root_inode()
{
    return inode_table;
}

void iput(inode_t *inode)
{
    if (!inode)
        return;
    inode->op->close(inode);
}

void inode_init()
{
    for (size_t i = 0; i < NR_INODE; i++)
    {
        inode_t *inode = &inode_table[i];
        inode->super = NULL;
    }
}